﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using System.Security.Permissions;
using SPMS.Utility.Properties;

namespace SPMS.Utility
{
    /// <summary>
    /// 反射处理辅助类
    /// </summary>
    /// <remarks></remarks>
    /// <history>
    /// [zanezeng]   2008-9-23 4:38 PM    Created
    /// </history>
    public static class ReflectionUtility
    {
        /// <summary>
        /// 通过方法名称获得指定类型的方法列表
        /// </summary>
        /// <param name="type">实现方法的类型</param>
        /// <param name="methodName">方法的名称</param>
        /// <param name="ignoreCase">是否忽略方法名称的大小写</param>
        /// <returns>类型中与指定名称一致的所有方法</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-10-23 11:11 AM    Created
        /// </history>
        public static MemberInfo[] GetMethodsByName(Type type, string methodName, bool ignoreCase)
        {
            //判断类型和方法名称是否为空
            if (null == type || !StringUtility.HasText(methodName))
            {
                //返回空数组
                return new MemberInfo[0];
            }

            //绑定标志
            BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

            //判断是否忽略大小写
            if (ignoreCase)
            {
                flags |= BindingFlags.IgnoreCase;
            }

            //检索成员
            return type.FindMembers(MemberTypes.Method, flags, null, null);
        }

        /// <summary>
        /// 判断指定的类型是否包含指定名称的方法
        /// </summary>
        /// <param name="type">用于判断的类型</param>
        /// <param name="methodName">方法的名称</param>
        /// <param name="ignoreCase">是否忽略方法名称的大小写</param>
        /// <returns>
        /// 	<c>true</c>：包含指定名称的方法<br/>
        /// 	<c>false</c>：没有包含指定名称的方法
        /// </returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-10-23 1:15 PM    Created
        /// </history>
        public static bool HasMethod(Type type, string methodName, bool ignoreCase)
        {
            //获得指定名称的方法
            MemberInfo[] members = GetMethodsByName(type, methodName, ignoreCase);

            //返回
            return members.Length > 0;
        }

        /// <summary>
        /// 判断指定的类型是否实现了指定的接口类型
        /// </summary>
        /// <param name="type">用于判断的类型</param>
        /// <param name="interfaceType">实现的接口类型</param>
        /// <returns>
        /// 	<c>true</c>：实现了指定的接口类型<br/>
        /// 	<c>false</c>：没有实现指定的接口类型
        /// </returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-10-23 11:32 AM    Created
        /// </history>
        public static bool IsImplementInterface(Type type, Type interfaceType)
        {
            //判断类型是否指定
            if (null == type || null == interfaceType)
            {
                //认为没有实现
                return false;
            }

            //判断接口类型是否为接口
            if (!interfaceType.IsInterface)
            {
                //如果不是接口，认为没有实现
                return false;
            }

            //类型过滤器
            TypeFilter filter = delegate(Type checkType, object filterCriteria)
            {
                //判断是否为同一个类型
                return object.ReferenceEquals(checkType, filterCriteria);
            };

            //检索接口
            if (type.FindInterfaces(filter, interfaceType).Length > 0)
            {
                //返回已经实现
                return true;
            }

            //返回没有实现
            return false;
        }

        /// <summary>
        /// 根据指定的检索条件在指定的类型中检索满足检索条件的方法
        /// </summary>
        /// <param name="type">目标类型</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="argumentCount">期望的参数个数</param>
        /// <param name="flags">反射绑定标识</param>
        /// <param name="ignoreCase">是否忽略方法名称的大小写</param>
        /// <returns>一个包含所有满足检索条件的方法信息数组。如果没有满足条件的方法，则返回空数组</returns>
        /// <exception cref="System.ArgumentNullException">type为空、methodName为空或者为空字符串</exception>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-10-28 11:14    Created
        /// </history>
        public static MethodInfo[] FindMethods(Type type, string methodName, int argumentCount, BindingFlags flags, bool ignoreCase)
        {
            return FindMethods(type, methodName, argumentCount, flags, 0, ignoreCase);
        }

        /// <summary>
        /// 根据指定的检索条件在指定的类型中检索满足检索条件的方法
        /// </summary>
        /// <param name="type">目标类型</param>
        /// <param name="methodName">方法名称</param>
        /// <param name="argumentCount">期望的参数个数</param>
        /// <param name="flags">反射绑定标识</param>
        /// <param name="genericArgumentCount">泛型参数的个数，如果指定为0，表示不是泛型方法</param>
        /// <param name="ignoreCase">是否忽略方法名称的大小写</param>
        /// <returns>一个包含所有满足检索条件的方法信息数组。如果没有满足条件的方法，则返回空数组</returns>
        /// <exception cref="System.ArgumentNullException">type为空、methodName为空或者为空字符串</exception>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-10-28 15:41    Created
        /// </history>
        public static MethodInfo[] FindMethods(Type type, string methodName, int argumentCount, BindingFlags flags, int genericArgumentCount, bool ignoreCase)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(type, "type");
            ArgumentAssert.AssertStringArgumentNotNullOrEmpty(methodName, "methodName");

            //创建过滤委托
            MemberFilter filter = delegate(MemberInfo member, object filterCriteria)
            {
                //转化为方法信息
                MethodBase method = member as MethodBase;

                //判断是否是方法
                if (null != method)
                {
                    //如果指定了方法名称，则需要比较方法名称是否一致
                    if (!string.IsNullOrEmpty(methodName) && !PatternUtility.IsSimpleMatch(methodName, method.Name, ignoreCase))
                    {
                        //如果方法名称不一致，则认为不匹配
                        return false;
                    }

                    //判断是否指定了泛型类型参数
                    if (genericArgumentCount > 0)
                    {
                        //判断是否包含了泛型类型参数
                        if (!method.ContainsGenericParameters)
                        {
                            //如果没有包含，则认为不匹配
                            return false;
                        }

                        //获得泛型类型参数的个数
                        int actualGenericCount = GetGenericTypeArgumentCount(method);

                        //比较泛型类型参数的个数与实际要求的泛型类型参数个数是否相等
                        if (actualGenericCount != genericArgumentCount)
                        {
                            //如果不等，则认为不匹配
                            return false;
                        }
                    }

                    //获得参数
                    ParameterInfo[] parameters = method.GetParameters();

                    //实际参数个数
                    int actualParameterCount = parameters.Length;

                    //如果实际参数大于期望的参数个数，那么判断最后一个参数是否为可选数组参数
                    if (argumentCount > actualParameterCount)
                    {
                        //如果最后一个参数不是可选数组参数，则认为不匹配
                        if (!IsParamParameter(parameters[actualParameterCount - 1]))
                        {
                            return false;
                        }
                    }
                    else if (argumentCount < actualParameterCount)
                    {
                        //如果期望的参数个数小于实际的参数个数，那么判判断后续的参数定义是否为可选参数
                        if (!parameters[actualParameterCount].IsOptional)
                        {
                            //如果不是可选参数，则认为不匹配
                            return false;
                        }
                    }
                }

                //默认认为匹配
                return true;
            };

            //检索成员
            return (MethodInfo[])type.FindMembers(MemberTypes.Method, flags, filter, null);
        }

        /// <summary>
        /// 获得指定方法的可选参数的个数
        /// </summary>
        /// <param name="method">用于获得可选参数的方法</param>
        /// <returns>可选参数的个数</returns>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="method"/>为Null</exception>
        /// <history>
        /// [zanezeng]   2008-11-24 8:49    Created
        /// </history>
        public static int GetOptionalParameterCount(MethodBase method)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(method, "method");

            //获得方法的参数列表
            ParameterInfo[] parameters = method.GetParameters();

            //返回计数
            return parameters.Count((parameter) =>
            {
                return parameter.IsOptional;
            });
        }

        /// <summary>
        /// 获得指定方法的开放泛型类型参数的个数
        /// </summary>
        /// <param name="method">用于获得可选参数的方法</param>
        /// <returns>开放泛型类型参数的个数</returns>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="method"/>为Null</exception>
        /// <history>
        /// [zanezeng]   2008-11-24 8:49    Created
        /// </history>
        public static int GetGenericTypeArgumentCount(MethodBase method)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(method, "method");

            //判断是否包含泛型类型参数
            if (!method.ContainsGenericParameters)
            {
                //如果不包含，则返回0
                return 0;
            }

            //判断是否为构造方法
            if (method is ConstructorInfo)
            {
                //如果是构造函数需要特殊处理
                return method.GetGenericArguments().Count((type) =>
                {
                    return type.IsGenericParameter;
                });
            }
            else
            {
                //如果不是构造方法，直接返回泛型参数的个数
                return method.GetGenericArguments().Length;
            }
        }

        /// <summary>
        /// 判断指定的方法是否包含可选数组参数
        /// </summary>
        /// <param name="method">用于判断是否包含可选数组参数的方法</param>
        /// <returns>
        /// 	<c>true</c>：包含可选数组参数<br/>
        /// 	<c>false</c>：不包含可选数组参数
        /// </returns>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="method"/>为Null</exception>
        /// <history>
        /// [zanezeng]   2008-11-24 8:51    Created
        /// </history>
        public static bool HasParamParameter(MethodBase method)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(method, "method");

            //获得方法的参数列表
            ParameterInfo[] parameters = method.GetParameters();

            //判断列表是否为空
            if (CollectionUtility.IsNullOrEmpty(parameters))
            {
                //如果没有包含参数则返回FALSE
                return false;
            }

            //判断最后一个参数是否为可选数组参数
            return IsParamParameter(parameters[parameters.Length - 1]);
        }

        /// <summary>
        /// 判断是否可以使用指定的参数值调用指定的方法
        /// </summary>
        /// <param name="method">方法信息</param>
        /// <param name="argumentValues">尝试调用方法的参数</param>
        /// <returns>
        /// 	<c>true</c>：能够使用指定的参数调用方法<br/>
        /// 	<c>false</c>：不能使用指定的参数调用方法
        /// </returns>
        /// <remarks></remarks>
        /// <exception cref="System.ArgumentNullException">method为Null</exception>
        /// <history>
        /// [zanezeng]   2008-10-28 16:00    Created
        /// </history>
        public static bool IsMethodCanInvokeByArguments(MethodBase method, object[] argumentValues)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(method, "method");

            //判断参数值是否为空
            if (null == argumentValues)
            {
                //定义为空数组
                argumentValues = ObjectUtility.EmptyObjects;
            }

            //获得参数值的个数
            int argLength = argumentValues.Length;

            //用于保存参数
            ParameterInfo parameter = null;

            //获得方法声明的参数
            ParameterInfo[] parameters = method.GetParameters();

            //循环参数进行比较
            for (int index = 0; index < parameters.Length; index++)
            {
                //获得参数
                parameter = parameters[index];

                //判断参数定义的个数已经超过了实际参数值的个数
                if (argLength <= index)
                {
                    //如果参数定义个数超过了实际参数值的个数，那么需要判断剩下的参数定义是否为可选数组参数或者为可选参数
                    return IsParamParameter(parameter) || parameter.IsOptional;
                }

                //比较参数值类型
                if (parameter.ParameterType.IsValueType)
                {
                    //如果参数类型为值类型，但是参数值为NULL时认为不匹配
                    if (null == argumentValues[index])
                    {
                        return false;
                    }
                }
                else
                {
                    //如果参数不是值类型需要比较类型是否兼容
                    if (null != argumentValues[index] && !parameter.ParameterType.IsAssignableFrom(argumentValues[index].GetType()))
                    {
                        //如果类型不兼容，则认为不匹配
                        return false;
                    }
                }
            }

            //获得最后一个参数定义
            parameter = parameters[parameters.Length - 1];

            //判断最后一个参数是否为可选数组参数
            if (!IsParamParameter(parameter))
            {
                //如果不是可选数组参数，则认为不匹配
                return false;
            }
            else
            {
                //如果是可选数组参数需要判断参数类型是否兼容
                //判断类型是否匹配
                Type parameterType = parameter.ParameterType;

                //循环比较
                for (int index = parameters.Length; index < argumentValues.Length; index++)
                {
                    //比较参数值类型
                    if (parameter.ParameterType.IsValueType)
                    {
                        //如果参数类型为值类型，但是参数值为NULL时认为不匹配
                        if (null == argumentValues[index])
                        {
                            return false;
                        }
                    }
                    else
                    {
                        //如果参数不是值类型需要比较类型是否兼容
                        if (null != argumentValues[index] && !parameter.ParameterType.IsAssignableFrom(argumentValues[index].GetType()))
                        {
                            //如果类型不兼容，则认为不匹配
                            return false;
                        }
                    }
                }
            }

            //默认认为匹配
            return true;
        }

        /// <summary>
        /// 判断指定的参数是否为[params]类型参数
        /// </summary>
        /// <param name="parameter">用于判断的参数信息</param>
        /// <returns>
        /// 	<c>true</c>：是[params]类型参数<br/>
        /// 	<c>false</c>：不是[params]类型参数
        /// </returns>
        /// <remarks>如果传入参数为NULL，那么总是返回FALSE</remarks>
        /// <history>
        /// [zanezeng]   2008-10-28 13:42    Created
        /// </history>
        public static bool IsParamParameter(ParameterInfo parameter)
        {
            //判断是否为NULL
            if (null == parameter)
            {
                return false;
            }

            //判断是否设定了ParamArrayAttribute属性
            return parameter.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0;
        }

        /// <summary>
        /// 判断指定的参数是否为[ref或者out]类型参数
        /// </summary>
        /// <param name="parameter">用于判断的参数信息</param>
        /// <returns>
        /// 	<c>true</c>：是[ref或者out]类型参数<br/>
        /// 	<c>false</c>：不是[ref或者out]类型参数
        /// </returns>
        /// <remarks>如果传入参数为NULL，那么总是返回FALSE</remarks>
        /// <history>
        /// [zanezeng]   2009-2-5 11:03    Created
        /// </history>
        public static bool IsByRefParameter(ParameterInfo parameter)
        {
            //判断是否为NULL
            if (null == parameter)
            {
                return false;
            }

            //返回判定
            return parameter.ParameterType.IsByRef;
        }

        /// <summary>
        /// 获得指定枚举类型的字段类型
        /// </summary>
        /// <param name="enumType">枚举类型</param>
        /// <returns>指定枚举类型的字段类型</returns>
        /// <exception cref="E:ArgumentNullException"><paramref name="enumType"/>为Null</exception>
        /// <exception cref="E:ArgumentException"><paramref name="enumType"/>不是枚举类型</exception>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2009-2-6 17:09    Created
        /// </history>
        public static Type GetEnumFieldType(Type enumType)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(enumType, "enumType");

            //判断是否为枚举类型
            if (!enumType.IsEnum)
            {
                //抛出异常
                throw new ArgumentException(Resources.MSG_ENUM_REQUIRED, "enumType");
            }

            //获得元素类型码
            TypeCode code = Type.GetTypeCode(enumType);

            //根据类型码返回类型
            switch (code)
            {
                case TypeCode.SByte:
                    {
                        return typeof(SByte);
                    }
                case TypeCode.Byte:
                    {
                        return typeof(Byte);
                    }
                case TypeCode.Int16:
                    {
                        return typeof(Int16);
                    }
                case TypeCode.Int32:
                    {
                        return typeof(Int32);
                    }
                case TypeCode.Int64:
                    {
                        return typeof(Int64);
                    }
                case TypeCode.UInt16:
                    {
                        return typeof(UInt16);
                    }
                case TypeCode.UInt32:
                    {
                        return typeof(UInt32);
                    }
                case TypeCode.UInt64:
                    {
                        return typeof(UInt64);
                    }
                default:
                    {
                        throw new NotSupportedException();
                    }
            }
        }

        /// <summary>
        /// 获得指定参数信息数组的类型数组
        /// </summary>
        /// <param name="parameters">参数信息数组</param>
        /// <returns>包含参数信息数组的类型数组</returns>
        /// <remarks>如果输入的参数信息数组为NULL或者为空，则返回空数组</remarks>
        /// <history>
        /// [zanezeng]   2008-10-29 11:07    Created
        /// </history>
        public static Type[] GetParameterTypes(ParameterInfo[] parameters)
        {
            //判断是否为空
            if (CollectionUtility.IsNullOrEmpty(parameters))
            {
                //返回空数组
                return Type.EmptyTypes;
            }

            //创建查询
            var queryParameters = from parameter in parameters
                                  select parameter.ParameterType;

            //返回参数类型
            return queryParameters.ToArray();
        }

        /// <summary>
        /// 将指定的类型名称格式化为泛型名称
        /// </summary>
        /// <param name="typeName">类型名称</param>
        /// <param name="genericArgumnetCount">泛型参数的个数</param>
        /// <returns>格式化之后的泛型名称</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-20 15:21    Created
        /// </history>
        public static string FormatGenericTypeName(string typeName, int genericArgumnetCount)
        {
            //判断是否为空
            if (!StringUtility.HasText(typeName))
            {
                //返回空字符串
                return string.Empty;
            }

            //判断泛型参数的个数
            if (0 >= genericArgumnetCount)
            {
                //如果泛型参数个数小于等于0，则直接返回
                return typeName;
            }

            //拆分名称
            string[] parts = StringUtility.SplitFirst(typeName, ',', false);

            //获得泛型后缀的位置
            int index = parts[0].IndexOf(GENERICTYPE_SUFFIX);

            //判断是否已经包含泛型后缀
            if (index != -1)
            {
                //如果已经包含则需要去掉
                parts[0] = parts[0].Substring(0, index);
            }

            //格式化
            parts[0] = string.Format("{0}{1}{2}", parts[0], GENERICTYPE_SUFFIX, genericArgumnetCount);

            //返回
            return string.Join(",", parts);
        }

        /// <summary>
        /// 获得泛型类型的显示名称
        /// </summary>
        /// <param name="type">要获得显示名称的泛型类型</param>
        /// <param name="withNamespace">是否需要包含类型的命名空间</param>
        /// <returns>指定泛型类型的显示名称</returns>
        /// <remarks>
        /// 	<![CDATA[
        /// 泛型类型的显示名称格式为：类型名称<泛型参数名称,泛型参数名称>
        /// ]]>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="type"/>为NULL</exception>
        /// <history>
        /// [zanezeng]               2009-3-19 12:22    创建
        /// </history>
        public static string GetGenericTypeDisplayName(Type type, bool withNamespace)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(type, "type");

            //获得类型名称
            string typeName = type.Name;

            //获得泛型后缀的位置
            int index = typeName.IndexOf(GENERICTYPE_SUFFIX);

            //判断是否已经包含泛型后缀
            if (index != -1)
            {
                //如果已经包含则需要去掉泛型后缀
                typeName = typeName.Substring(0, index);
            }

            //用于保存名称
            StringBuilder builder = new StringBuilder();

            //判断是否要包含命名空间
            if (withNamespace)
            {
                //添加命名空间
                builder.Append(type.Namespace);

                //添加分隔符
                builder.Append(".");
            }

            //添加类型名称
            builder.Append(typeName);

            //获得泛型参数
            Type[] parameters = type.GetGenericArguments();

            //判断是否有泛型参数
            if (null == parameters || 0 == parameters.Length)
            {
                //如果没有泛型参数，则直接返回
                return builder.ToString();
            }

            //添加括号
            builder.Append("<");

            //是否需要添加逗号
            bool needComma = false;

            //循环添加泛型类型
            foreach (Type parameter in parameters)
            {
                //判断是否需要添加逗号
                if (needComma)
                {
                    //添加逗号
                    builder.Append(",");
                }

                //获得类型名称
                typeName = GetGenericTypeDisplayName(parameter, withNamespace);

                //添加类型名称
                builder.Append(typeName);

                //设置需要添加逗号
                needComma = true;
            }

            //添加括号
            builder.Append(">");

            //返回类型名称
            return builder.ToString();
        }

        /// <summary>
        /// 判断指定的类型名称是否为泛型
        /// </summary>
        /// <param name="typeName">类型的名称</param>
        /// <returns>
        /// 	<c>true</c>：是泛型<br/>
        /// 	<c>false</c>：不是泛型
        /// </returns>
        /// <remarks>如果输入的字符为Null或者为空字符串，总是返回False</remarks>
        /// <history>
        /// [zanezeng]   2008-11-20 15:28    Created
        /// </history>
        public static bool IsGenericType(string typeName)
        {
            //判断是否为空
            if (string.IsNullOrEmpty(typeName))
            {
                return false;
            }

            //返回
            return typeName.Contains(GENERICTYPE_SUFFIX);
        }

        /// <summary>
        /// 通过指定的类型名称创建泛型类型
        /// </summary>
        /// <param name="typeName">类型名称</param>
        /// <param name="genericArguments">泛型参数</param>
        /// <returns>创建的泛型类型</returns>
        /// <exception cref="System.ArgumentNullException"><paramref name="genericArguments"/>为Null</exception>
        /// <exception cref="System.ArgumentException"><paramref name="genericArguments"/>为空数组或者包含Null</exception>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-21 11:49    Created
        /// </history>
        public static Type MakeGenericType(string typeName, Type[] genericArguments)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(genericArguments, "genericArguments");

            //保存原始长度
            int argsLength = genericArguments.Length;

            //判断是否为空数组
            if (0 == argsLength)
            {
                //抛出异常
                throw new ArgumentException(Resources.MSG_COLLECTION_EMPTY, "genericArguments");
            }

            //去掉参数中的NULL值
            genericArguments = CollectionUtility.TrimNull<Type>(genericArguments);

            //判断是否为空
            if (genericArguments.Length == 0 || genericArguments.Length != argsLength)
            {
                //抛出异常
                throw new ArgumentException(Resources.MSG_COLLECTION_CONTAINSNULL, "genericArguments");
            }

            //格式化泛型类型名称
            typeName = FormatGenericTypeName(typeName, argsLength);

            //创建类型
            Type definitionType = Type.GetType(typeName, true, true);

            //创建泛型
            return definitionType.MakeGenericType(genericArguments);
        }

        /// <summary>
        /// 尝试获得指定属性的默认值
        /// </summary>
        /// <param name="property">属性信息</param>
        /// <param name="defaultValue">用于返回获得的默认值</param>
        /// <returns>
        /// 	<c>true</c>：指定的属性存在默认值<br/>
        /// 	<c>false</c>：指定的属性不存在默认值
        /// </returns>
        /// <exception cref="T:ArgumentNullException"><paramref name="property"/>为Null</exception>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-12-25 17:37    Created
        /// </history>
        public static bool TryGetDefaultValue(PropertyInfo property, out object defaultValue)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(property, "property");

            //设置默认值
            defaultValue = null;

            //获得默认值特性
            object[] attributes = property.GetCustomAttributes(typeof(DefaultValueAttribute), true);

            //判断是否存在默认值
            if (CollectionUtility.IsNullOrEmpty(attributes))
            {
                return false;
            }

            //获得默认值
            defaultValue = ((DefaultValueAttribute)attributes[0]).Value;

            //返回存在
            return true;
        }

        /// <summary>
        /// 获得指定类型的默认构造函数
        /// </summary>
        /// <param name="type">要获得构造函数的类型</param>
        /// <returns>指定类型的默认构造函数。如果没有找到则返回Null</returns>
        /// <remarks></remarks>
        /// <exception cref="E:ArgumentNullException"><paramref name="type"/>为Null</exception>
        /// <history>
        /// [zanezeng]   2009-1-15 9:43    Created
        /// </history>
        public static ConstructorInfo GetDefaultConstructor(Type type)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(type, "type");

            //检索构造函数
            return type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
        }

        /// <summary>
        /// 获得指定方法的原始声明类型
        /// </summary>
        /// <param name="method">要获得原始声明类型的方法</param>
        /// <returns>获得指定方法的原始声明类型</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2009-2-24 12:05    Created
        /// </history>
        public static Type GetMethodOriginalDeclaringType(MethodInfo method)
        {
            //用于保存基类方法
            MethodInfo baseMethod = null;

            //获得原始基类方法
            do
            {
                //获得基类方法
                baseMethod = method.GetBaseDefinition();

                //判断基类方法是否存在
                if (method.DeclaringType == baseMethod.DeclaringType)
                {
                    return method.DeclaringType;
                }

                //记录基类方法
                method = baseMethod;
            }
            while (true);
        }

        /// <summary>
        /// 判断指定的自定义特性是否能够继承
        /// </summary>
        /// <param name="attribute">要进行判定的自定义特性</param>
        /// <returns>
        ///     <c>true</c>：能继承<br/>
        /// 	<c>false</c>：不能继承
        /// </returns>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="attribute"/>为NULL</exception>
        /// <history>
        /// [zanezeng]               2009-3-19 11:14    创建
        /// </history>
        public static bool IsCustomAttributeInheritable(Attribute attribute)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(attribute, "attribute");

            //获得特性
            object[] attributes = attribute.GetType().GetCustomAttributes(typeof(AttributeUsageAttribute), true);

            //判断是否有特性
            if (null == attributes || 0 == attributes.Length)
            {
                //如果没有特性，则默认为不能继承
                return false;
            }

            //获得特性使用特性
            AttributeUsageAttribute usageAttribute = attributes[0] as AttributeUsageAttribute;

            //返回是否允许继承
            return usageAttribute.Inherited;
        }

        /// <summary>
        /// 确定当前的<paramref name="targetType"/>类型实例是否可以从指定的<paramref name="sourceType"/>类型实例分配
        /// </summary>
        /// <param name="sourceType">源类型</param>
        /// <param name="targetType">模板类型</param>
        /// <returns>
        ///     <c>true</c>：可以分配<br/>
        /// 	<c>false</c>：不可以分配</returns>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="sourceType"/>为NULL</exception>
        /// <exception cref="ArgumentNullException"><paramref name="targetType"/>为NULL</exception>
        /// <history>
        /// [zanezeng]               2009-3-19 15:40    创建
        /// </history>
        public static bool IsAssignableFrom(Type sourceType, Type targetType)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(sourceType, "sourceType");
            ArgumentAssert.AssertArgumentNotNull(targetType, "targetType");

            //判断目标类型是否为Object
            if (targetType == typeof(object))
            {
                //如果目标类型，则总是认为可以分配
                return true;
            }

            //判断是否可以转换
            try
            {
                return targetType.IsAssignableFrom(sourceType);
            }
            catch (NotSupportedException)
            {
            }

            //默认返回不支持直接分配
            return false;
        }

        #region ---Const

        /// <summary>
        /// 泛型类型的后缀
        /// </summary>
        public static readonly char GENERICTYPE_SUFFIX = '`';

        #endregion
    }
}
